/*
 * Copyright 2010 Brian Watkins
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package bw.tools;

import bw.util.*;
import bw.os.*;
import bw.net.*;
import bw.news.*;
import bw.cal.*;
import bw.note.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class DatastoreMigrator extends HttpServlet
{

    public void doGet ( HttpServletRequest req, HttpServletResponse res )
        throws ServletException, IOException
    {
        if ( !"true".equals( req.getParameter( "doMigrate" ) ) )
        {
            return;
        }

        //we are set up to migrate from the http object reader to the google datastore
        String root = getServletContext().getInitParameter( "objectStore.httpReader.root" );
        HttpObjectReader source = new HttpObjectReader( root );

        //get the url to fetch news source data from
        String nsURL = getServletContext().getInitParameter( "dataMigrator.newsSourceURL" );

        res.setContentType( "text/plain" );
        PrintWriter out = res.getWriter();

        out.println( "Migrating news ..." );
        try
        {
            migrateNews( out, source, nsURL );
        }
        catch ( Exception ex )
        {
            Log.getInstance().write( "Problem migrating news!", ex );
        }
        

        out.println( "Migrating events ..." );
        try
        {
            migrateEvents( out, source );
        }
        catch ( Exception ex )
        {
            Log.getInstance().write( "Problem migrating events!", ex );
        }

        out.println( "Migrating notes ..." );
        try
        {
            migrateNotes( out, source );
        }
        catch ( Exception ex )
        {
            Log.getInstance().write( "Problem migrating notes!", ex );
        }

        out.println( "Done." );
        out.close();
    }

    private void migrateNews ( PrintWriter out, PersistentObjectReader dataSource, 
                               String newsSourceURL )
        throws Exception
    {
        NewsManager manager = NewsManager.getInstance();

        //get the list of categories
        Vector categories = (Vector) dataSource.read( NewsManager.NEWS_MANAGER_KEY );

        for ( Enumeration e = categories.elements(); e.hasMoreElements(); )
        {
            NewsCategory cat = (NewsCategory) e.nextElement();

            //create the new category based on this one
            out.println( "Creating new category: " + cat.getName() );
            int catId = manager.newNewsCategory( cat.getName() ).getId();

            Vector curCats = manager.newsCategories();
            NewsCategory newCat = manager.getNewsCategoryForId( curCats, catId );

            //get the list of sources
            Vector sourceIds = cat.getSourceIds();
            for ( Enumeration f = sourceIds.elements(); f.hasMoreElements(); )
            {
                String id = (String) f.nextElement();
                //Log.getInstance().write( "Looking for news source with id: " + id );
                
                NetResource r = new NetResource( newsSourceURL + id );
                String sourceInfo = Util.readStream( r.getInputStream() ).trim();
                //Log.getInstance().write( "Source info: " + sourceInfo );
                
                StringTokenizer st = new StringTokenizer( sourceInfo, "," );
                NewsSource newNS = manager.newNewsSource( st.nextToken(), st.nextToken(), 
                                                          st.nextToken(), 
                                                          Integer.parseInt( st.nextToken() ) );
                String username = st.nextToken();
                String password = st.nextToken();
                if ( !"null".equals( username) && !"null".equals( password ) )
                {
                    newNS.setUsername( username );
                    newNS.setPassword( password );
                }
                
                out.println( "Migrating news source: " + newNS.getName() );
                newCat.addNewsSource( newNS );
                manager.syncChanges( curCats );
            }
                        
            out.println( "Done with category: " + newCat.getName() );
        }

        out.println( "Done migrating news." );
    }

    private void migrateEvents ( PrintWriter out, PersistentObjectReader source )
        throws Exception
    {
        out.println( "Migrating day events ..." );
        Hashtable dayEvts = (Hashtable) source.read( CalendarEventManager.EVENT_MGR_DAY_EVTS );
        ObjectStore.getInstance().put( CalendarEventManager.EVENT_MGR_DAY_EVTS, dayEvts );

        out.println( "Migrating week events ..." );
        Hashtable weekEvts = (Hashtable) source.read( CalendarEventManager.EVENT_MGR_WEEK_EVTS );
        ObjectStore.getInstance().put( CalendarEventManager.EVENT_MGR_WEEK_EVTS, weekEvts );

        out.println( "Migrating year events ..." );
        Hashtable yearEvts = (Hashtable) source.read( CalendarEventManager.EVENT_MGR_YEAR_EVTS );
        ObjectStore.getInstance().put( CalendarEventManager.EVENT_MGR_YEAR_EVTS, yearEvts );
    }

    private void migrateNotes ( PrintWriter out, PersistentObjectReader source )
        throws Exception
    {
        out.println( "Migrating notes from home page ..." );
        Vector homeNotes = (Vector) source.read( "WD_NOTE_home" );
        ObjectStore.getInstance().put( "WD_NOTE_home", homeNotes );

        out.println( "Migrating notes from notebook ..." );
        NotebookManager manager = new NotebookManager();

        Vector defaultPageNotes = (Vector) source.read( "WD_NOTE_NoteBookMain" );
        ObjectStore.getInstance().put( "WD_NOTE_NoteBookMain", defaultPageNotes );

        Vector pages = (Vector) source.read( NotebookManager.NOTEBOOK_INDEX );
        for ( Enumeration e = pages.elements(); e.hasMoreElements(); )
        {
            String pageName = (String) e.nextElement();
            out.println( "Migrating notes for page: " + pageName );
            manager.addPage( pageName );
            Vector pageNotes = (Vector) source.read( "WD_NOTE_" + pageName );
            ObjectStore.getInstance().put( "WD_NOTE_" + pageName, pageNotes );
        }
    }
}